//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package com.eastrobot.doc.poitlconvert.service.impl;

import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.exception.RenderException;
import com.deepoove.poi.policy.RenderPolicy;
import com.deepoove.poi.render.compute.EnvModel;
import com.deepoove.poi.render.compute.RenderDataCompute;
import com.deepoove.poi.render.processor.DocumentProcessor;
import com.deepoove.poi.render.processor.EnvIterator;
import com.deepoove.poi.resolver.TemplateResolver;
import com.deepoove.poi.template.ElementTemplate;
import com.deepoove.poi.template.MetaTemplate;
import com.deepoove.poi.template.run.RunTemplate;
import com.deepoove.poi.util.ReflectionUtils;
import com.deepoove.poi.util.TableTools;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import lombok.extern.slf4j.Slf4j;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
import org.apache.poi.xwpf.usermodel.XWPFTableRow;
import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlObject;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRow;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTcPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTVMerge;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STMerge;

@Slf4j
public class CustomerLoopRowTableRenderPolicy implements RenderPolicy {
    private String prefix;
    private String suffix;
    private boolean onSameLine;

    public CustomerLoopRowTableRenderPolicy() {
        this(false);
    }

    public CustomerLoopRowTableRenderPolicy(boolean onSameLine) {
        this("{", "}", onSameLine);
    }

    public CustomerLoopRowTableRenderPolicy(String prefix, String suffix) {
        this(prefix, suffix, false);
    }

    public CustomerLoopRowTableRenderPolicy(String prefix, String suffix, boolean onSameLine) {
        this.prefix = prefix;
        this.suffix = suffix;
        this.onSameLine = onSameLine;

    }

    public void render(ElementTemplate eleTemplate, Object data, XWPFTemplate template) {
        RunTemplate runTemplate = (RunTemplate)eleTemplate;
        XWPFRun run = runTemplate.getRun();

        try {
            if (!TableTools.isInsideTable(run)) {
                throw new IllegalStateException("The template tag " + runTemplate.getSource() + " must be inside a table");
            } else {
                log.info("CustomerLoopRowTableRenderPolicy render 开始");

                XWPFTableCell tagCell = (XWPFTableCell)((XWPFParagraph)run.getParent()).getBody();
                XWPFTable table = tagCell.getTableRow().getTable();
                run.setText("", 0);
                int templateRowIndex = this.getTemplateRowIndex(tagCell);

                if (null != data && data instanceof Iterable) {
//                    Iterator<?> iterator = ((Iterable)data).iterator();
                    XWPFTableRow templateRow = table.getRow(templateRowIndex);
                    TemplateResolver resolver = new TemplateResolver(template.getConfig().copy(this.prefix, this.suffix));
                    boolean firstFlag = true;
                    int index = 0;

                    List<XWPFTableRow> rows = table.getRows();
                    Iterator<XWPFTableRow> rowsI = ((Iterable)rows).iterator();
                    // 根据模版去遍历
                    boolean rowshasNext = rowsI.hasNext();

                    while(rowshasNext) {
//                        XWPFTableRow nextRow = rowsI.next();
                        System.out.println("当前行下标"+index);
                        templateRow = table.getRow(index);

                        rowsI.next();
                        rowshasNext = rowsI.hasNext();
                        index++;

                        if(index <=  templateRowIndex){
                            continue;
                        }
//                        Object root = iterator.next();
//                        boolean datahasNext = iterator.hasNext();

//                        int insertPosition = templateRowIndex++;
//                        table.insertNewTableRow(insertPosition);
//                        this.setTableRow(table, templateRow, insertPosition);
//                        XmlCursor newCursor = templateRow.getCtRow().newCursor();
//                        newCursor.toPrevSibling();
//                        XmlObject object = newCursor.getObject();
//                        XWPFTableRow nextRow = new XWPFTableRow((CTRow)object, table);
//                        XWPFTableRow nextRow = new XWPFTableRow((CTRow)object, table);
                        if (!firstFlag) {

                            List<XWPFTableCell> tableCells = templateRow.getTableCells();
                            Iterator cellIterator = tableCells.iterator();

                            while(cellIterator.hasNext()) {
                                XWPFTableCell cell = (XWPFTableCell)cellIterator.next();
                                CTTcPr tcPr = TableTools.getTcPr(cell);
                                CTVMerge vMerge = tcPr.getVMerge();
                                if (null != vMerge && STMerge.RESTART == vMerge.getVal()) {
                                    vMerge.setVal(STMerge.CONTINUE);
                                }
                            }
                        } else {
                            firstFlag = false;
                        }

//                        this.setTableRow(table, nextRow, insertPosition);
                        RenderDataCompute dataCompute = template.getConfig().getRenderDataComputeFactory().newCompute(EnvModel.of( new HashMap<String, Object>() {{
                            put(eleTemplate.getTagName(), data);
                        }}, EnvIterator.makeEnv(index, rowshasNext)));
                        System.out.println("当前行cells");

                        List<XWPFTableCell> cells = templateRow.getTableCells();
                        cells.forEach((cellx) -> {
                            List<MetaTemplate> templates = resolver.resolveBodyElements(cellx.getBodyElements());
                            (new DocumentProcessor(template, resolver, dataCompute)).process(templates);
                        });

                    }
                    System.out.println(index+"下标行遍历循环完毕");
                }

//                table.removeRow(templateRowIndex);
                this.afterloop(table, data);
                System.out.println("afterloop完毕");

            }
        } catch (Exception e) {
            throw new RenderException("HackLoopTable for " + eleTemplate + "error: " + e.getMessage(), e);
        }
    }

    private int getTemplateRowIndex(XWPFTableCell tagCell) {
        XWPFTableRow tagRow = tagCell.getTableRow();
        return this.onSameLine ? this.getRowIndex(tagRow) : this.getRowIndex(tagRow) + 1;
    }

    protected void afterloop(XWPFTable table, Object data) {
        System.out.println("afterloop");

    }

    private void setTableRow(XWPFTable table, XWPFTableRow templateRow, int pos) {
        List<XWPFTableRow> rows = (List)ReflectionUtils.getValue("tableRows", table);
        rows.set(pos, templateRow);
        table.getCTTbl().setTrArray(pos, templateRow.getCtRow());
    }

    private int getRowIndex(XWPFTableRow row) {
        List<XWPFTableRow> rows = row.getTable().getRows();
        return rows.indexOf(row);
    }
}
